From: Keir Fraser Date: Fri, 16 Oct 2009 07:28:47 +0000 (+0100) Subject: vt-d: Fixpanic in msi_msg_read_remap_rte with acpi=off X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~13218 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22?a=commitdiff_plain;h=4cf3febf20b3e6e910e5ee243471a55301ba64a5;p=xen.git vt-d: Fixpanic in msi_msg_read_remap_rte with acpi=off Xen panics when "acpi=off noacpi" is set. Problem is caused by dereferencing NULL pointer in drhd after calling acpi_find_matched_drhd_unit. As acpi_find_matched_drhd_unit can return NULL, checks has to be done before returned value is used. From: Miroslav Rezanina Signed-off-by: Keir Fraser --- diff --git a/xen/drivers/passthrough/vtd/intremap.c b/xen/drivers/passthrough/vtd/intremap.c index b4ab696243..24e22be320 100644 --- a/xen/drivers/passthrough/vtd/intremap.c +++ b/xen/drivers/passthrough/vtd/intremap.c @@ -563,7 +563,8 @@ void msi_msg_read_remap_rte( struct iommu *iommu = NULL; struct ir_ctrl *ir_ctrl; - drhd = acpi_find_matched_drhd_unit(pdev); + if ( (drhd = acpi_find_matched_drhd_unit(pdev)) == NULL ) + return; iommu = drhd->iommu; ir_ctrl = iommu_ir_ctrl(iommu); @@ -581,7 +582,8 @@ void msi_msg_write_remap_rte( struct iommu *iommu = NULL; struct ir_ctrl *ir_ctrl; - drhd = acpi_find_matched_drhd_unit(pdev); + if ( (drhd = acpi_find_matched_drhd_unit(pdev)) == NULL ) + return; iommu = drhd->iommu; ir_ctrl = iommu_ir_ctrl(iommu); diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c index 157acfc24e..4dabe6f4ec 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -1343,7 +1343,8 @@ static int reassign_device_ownership( if (!pdev) return -ENODEV; - drhd = acpi_find_matched_drhd_unit(pdev); + if ( (drhd = acpi_find_matched_drhd_unit(pdev)) == NULL ) + return -ENODEV; pdev_iommu = drhd->iommu; domain_context_unmap(source, bus, devfn); @@ -1357,7 +1358,7 @@ static int reassign_device_ownership( for_each_pdev ( source, pdev ) { drhd = acpi_find_matched_drhd_unit(pdev); - if ( drhd->iommu == pdev_iommu ) + if ( drhd && drhd->iommu == pdev_iommu ) { found = 1; break;